package com.mazaiting.rtda.heap;

import cn.hutool.core.util.ObjectUtil;
import com.mazaiting.classfile.attr.MemberInfo;
import com.mazaiting.classfile.attr.info.CodeAttribute;
import lombok.Getter;

import java.util.Arrays;

/**
 * 方法
 *
 * @author mazaiting
 * @since 2021/8/16
 */
@Getter
public class MtMethod extends MtClassMember {
    /**
     * 最大栈深
     */
    private int maxStack;
    /**
     * 最大局部变量表
     */
    private int maxLocals;
    /**
     * 二进制代码
     */
    private byte[] code;

    /**
     * 创建方法数组
     * @param mtClass 当前类字节码
     * @param memberInfos 方法信息
     * @return 方法数组
     */
    public static MtMethod[] newMethods(MtClass mtClass, MemberInfo[] memberInfos) {
        MtMethod[] methods = new MtMethod[memberInfos.length];
        for (int i = 0; i < memberInfos.length; i++) {
            MtMethod method = new MtMethod();
            method.setMtClass(mtClass);
            method.copyMemberInfo(memberInfos[i]);
            method.copyAttributes(memberInfos[i]);
            methods[i] = method;
        }
        return methods;
    }

    /**
     * 复制属性
     * @param info 成员信息
     */
    public void copyAttributes(MemberInfo info) {
        CodeAttribute attr = info.codeAttribute();
        if (ObjectUtil.isNotNull(attr)) {
            this.maxLocals = attr.getMaxLocals();
            this.maxStack = attr.getMaxStack();
            this.code = attr.getCode();
        }
    }

    /**
     * 判断是否为同步
     * @return true: 包含; false: 不包含
     */
    public boolean isSynchronized() {
        return MtAccessFlags.isSynchronized(accessFlags);
    }

    /**
     * 判断是否为桥接

     * @return true: 包含; false: 不包含
     */
    public boolean isBridge() {
        return MtAccessFlags.isBridge(accessFlags);
    }

    /**
     * 判断是否为可变参数

     * @return true: 包含; false: 不包含
     */
    public boolean isVarargs() {
        return MtAccessFlags.isVarargs(accessFlags);
    }

    /**
     * 判断是否为本地方法

     * @return true: 包含; false: 不包含
     */
    public boolean isNative() {
        return MtAccessFlags.isNative(accessFlags);
    }

    /**
     * 判断是否为严格模式

     * @return true: 包含; false: 不包含
     */
    public boolean isStrict() {
        return MtAccessFlags.isStrict(accessFlags);
    }

    @Override
    public String toString() {
        return "MtMethod{" +
                "name='" + name + '\'' +
                ", descriptor='" + descriptor + '\'' +
                '}';
    }
}


















